# 单纯的重复不是迭代
"""i = 0
while True: # 死循环
    print(i)"""
#迭代是一重复的过程，每一次重复都是基于上一次的结果而来
"""l = ['a','b','c']
i = 0
while i < len(l): # 根据索引长度进行遍历
    print(i) # 打印每一次的索引值
    print(l[i]) # 打印每一次对应的索引元素内容
    i +=1  # 循环条件"""
"""
第一次循环：
0
a
第二次循环：
1
b
第三次循环：
2
c
"""

# 有哪些数据类型支持这样迭代取值：字符串、元组、列表、字典、集合
# 数据类型不可变的：字符串、元组  ||整数、浮点型
# 数据类型可变的：列表、集合、字典
# str1 = "asd"
# for i in str1:
#     """
#     第一次循环：i是a
#     第二次循环：i是s
#     第三次循环：i是d
#     """
#     print(i)
# tuple1 = (1,2,3)
# for i in tuple1:
#     """
#     第一次循环：i是1
#     第二次循环：i是2
#     第三次循环：i是3
#     """
#     print(i)
# list1 = [22,33,44]
# for i in list1:
#     """
#     第一次循环：i是22
#     第二次循环：i是33
#     第三次循环：i是44
#     """
#     print(i)
# dict1 = {"name":"好健康","age":19}
# for i in dict1:
#     """
#     第一次循环：i是name
#     第二次循环：i是age
#     """
#     print(i,end='\t')
# set1 = {1,2,3}
# for i in set1:
#     print(i)

# 可迭代对象
a = 1 # 整数类型
# a.__iter__() # 说明没有这个方法，整数不支持迭代
b = 1.1
# b.__iter__() # 没有这个方法，浮点型不支持迭代
c = "hello"
# c.__iter__() # 字符串类型支持迭代
d = ['a','c']
# d.__iter__() # 列表支持迭代
e = (1,2)
# e.__iter__() # 元组支持迭代
f = {1,2,3}
# f.__iter__() # 集合支持迭代
g = {"name":"好健康","age":19}
# g.__iter__() # 字典支持迭代
"""
通过上面的检查方式
可迭代对象有：
【字符串】、【列表】、【元组】、【集合】、【字典】
不可迭代对象有：
【整数】、【浮点型】
"""
# 迭代器
"""dic = {"x":1,"y":2,"z":3}
iter_dic = dic.__iter__() # 创建迭代器对象
# print(iter_dic) # 返回一个地址值：<dict_keyiterator object at 0x000001DA7EC55B80>
# 通过__next__()方法，取它的下一个值
print(iter_dic.__next__()) # x
print(iter_dic.__next__()) # y
print(iter_dic.__next__()) # z
# StopIteration应该被当成一种结束信号，代表迭代器取干净了
print(iter_dic.__next__()) # ？ 报错了，因为所有的迭代对象都取空了"""

# 迭代器误区
"""dic1 = {"x":1,"y":2,"z":3}
# 这样的话，就相当于每一次都创建了新的迭代器对象
print(dic1.__iter__().__next__()) # x
print(dic1.__iter__().__next__()) # x
print(dic1.__iter__().__next__()) # x
print(dic1.__iter__().__next__()) # x"""

# 迭代器为什么和for循环使用？

# 先看while循环
l1 = [1,2,3]
iter_l1 = l1.__iter__()
# while True:
#     print(next(iter_l1))  # 这个等于  iter_l1.__next__()
#     """
#     第一次打印输出为：1
#     第二次打印输出为：2
#     第三次打印输出为：3
#     第四次打印输出为：StopIteration
#     为了解决这个问题，可以捕捉异常
#     """
# while True:
#     try:
#         print(next(iter_l1)) # 尝试性去打印
#     except StopIteration as e: # 如果取空了，会报这个错
#         print(f"报错提示：{e}")
#         break # 取空了就没有必要循环了
#     finally:
#         print("本次输出结束！")
# for i in l1:
#     print(i) # 直接就可以不断的拿下一个值
"""
直接进行for循环，为咱们做了很多事情：
1、直接根据这个数据类型创建了迭代器
2、不断地循环访问下一个
3、直到都拿完了以后，会去捕捉异常处理，不会展示错误
"""

# 还记得range吗？
obj_iter = range(1,10)
# print(obj_iter) # 直接返回的就是原始打印的内容
# print(list(obj_iter)) # 可以直接转成列表对象去使用
# print(tuple(obj_iter)) # 可以直接转成元组对象去使用
# 创建迭代器对象
obj = obj_iter.__iter__()
# 结合__next__()方法不断访问下一个
"""print(obj.__next__()) # 1
print(obj.__next__()) # 2
print(obj.__next__()) # 3
print(obj.__next__()) # 4
print(obj.__next__()) # 5
print(obj.__next__()) # 6
print(obj.__next__()) # 7

#问题
print("迭代器的for循环下了三个鸡蛋的母鸡")
for i in obj:
    # 从1开始还是从8开始
    print(i) # 接着从8开始，因为前面有7个鸡蛋被拿走了
print("再次")
for i in obj:
    print(i) # 打印为空，迭代器对象没有值可以取了
print('可迭代对象的for循环没下蛋的母鸡')
for i in obj_iter:
    print(i) # 有值，相当于一个新的可迭代对象
print("再次")
for i in obj_iter:
    print(i) # 依然有值，一个新的可迭代对象
"""

# 生成器  yeild
def gg():
    a = 1 # 创建了一个a变量，初始值为1
    while True: # 死循环，不断的循环
        yield a # 生成器 ，也可以把他理解为return值
        a += 1 # 每一次a都会+=1

a1 = gg()
print(next(a1)) # 1
print(next(a1)) # 2
print(next(a1)) # 3









































